package com.zz.admin.internationalManagement.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zz.admin.internationalManagement.dto.I18nConfigDto;
import com.zz.admin.internationalManagement.entity.I18nConfig;
import com.zz.admin.internationalManagement.mapper.I18nConfigMapper;
import com.zz.admin.internationalManagement.service.I18nConfigService;
import com.zz.common.base.dto.PageListResultDto;
import com.zz.common.base.enums.BaseExceptionEnum;
import com.zz.common.base.param.QueryParam;
import com.zz.common.constants.BaseConstant;
import com.zz.common.exception.ExceptionFactory;
import com.zz.common.utils.common.UUIDGenerator;
import com.zz.common.utils.mapper.BeanMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


/**
 * 国际化配置表 服务实现类
 *
 * @author zhang.lei
 * @since 2025-07-13 14:12:57
 */
@Service
@Slf4j
public class I18nConfigServiceImpl extends ServiceImpl<I18nConfigMapper, I18nConfig> implements I18nConfigService {

    @Resource
    private I18nConfigMapper i18nConfigMapper;

    @Override
    public PageListResultDto<I18nConfigDto> queryWithPage(I18nConfigDto i18nConfigDto, QueryParam queryParam) {
        Page<I18nConfig> page = new Page<>(queryParam.getPageNum(), queryParam.getPageSize());
        QueryWrapper<I18nConfig> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        if (StringUtils.isNotBlank(i18nConfigDto.getLocale())) {
            wrapper.eq("locale", i18nConfigDto.getLocale());
        }
        if (StringUtils.isNotBlank(i18nConfigDto.getNamespace())) {
            wrapper.eq("namespace", i18nConfigDto.getNamespace());
        }
        if (StringUtils.isNotBlank(i18nConfigDto.getKeyPath())) {
            wrapper.eq("key_path", i18nConfigDto.getKeyPath());
        }
        if (StringUtils.isNotBlank(i18nConfigDto.getValue())) {
            wrapper.eq("value", i18nConfigDto.getValue());
        }
        if (StringUtils.isNotBlank(i18nConfigDto.getDescription())) {
            wrapper.eq("description", i18nConfigDto.getDescription());
        }
        if (StringUtils.isNotBlank(i18nConfigDto.getStatus())) {
            wrapper.eq("status", i18nConfigDto.getStatus());
        }
        page = i18nConfigMapper.selectPage(page, wrapper);
        List<I18nConfig> i18nConfigs = i18nConfigMapper.selectList(page, wrapper);
        List<I18nConfigDto> i18nConfigDtos = BeanMapper.mapList(i18nConfigs, I18nConfig.class, I18nConfigDto.class);
        return new PageListResultDto<>((int) page.getCurrent(), (int) page.getTotal(), queryParam.getPageSize(), i18nConfigDtos);
    }

    @Override
    public List<I18nConfigDto> queryWithNoPage(I18nConfigDto i18nConfigDto) {
        QueryWrapper<I18nConfig> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        List<I18nConfig> i18nConfigs = i18nConfigMapper.selectList(wrapper);
        return BeanMapper.mapList(i18nConfigs, I18nConfig.class, I18nConfigDto.class);
    }

    @Override
    public I18nConfigDto queryById(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }
        I18nConfig i18nConfig = i18nConfigMapper.selectById(id);
        if (i18nConfig == null || BaseConstant.YES.equals(i18nConfig.getDelFlag())) {
            return null;
        }
        return BeanMapper.map(i18nConfig, I18nConfigDto.class);
    }

    @Override
    public List<I18nConfigDto> queryByIds(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        List<I18nConfig> i18nConfigs = i18nConfigMapper.selectByIds(ids);
        if (CollectionUtils.isEmpty(i18nConfigs)) {
            return new ArrayList<>();
        }
        return BeanMapper.mapList(i18nConfigs, I18nConfig.class, I18nConfigDto.class);
    }

    @Override
    public Map<String, Map<String, Object>> queryByLocale(String locale) {
        QueryWrapper<I18nConfig> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        wrapper.eq("locale", locale);

        List<I18nConfig> i18nConfigs = i18nConfigMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(i18nConfigs)) {
            return Collections.emptyMap();
        }

        Map<String, Map<String, Object>> result = new HashMap<>();

        for (I18nConfig config : i18nConfigs) {
            String namespace = config.getNamespace();
            String keyPath = config.getKeyPath(); // 如 "confirm"
            String value = config.getValue();     // 如 "确定"

            // 分组构造结果
            result.computeIfAbsent(namespace, k -> new HashMap<>()).put(keyPath, value);
        }

        return result;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public I18nConfigDto save(I18nConfigDto i18nConfigDto) {
        // 根据业务修改
        return insert(i18nConfigDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<I18nConfigDto> saveBatch(List<I18nConfigDto> i18nConfigDtos) {
        // 根据业务修改
        return insertList(i18nConfigDtos);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public I18nConfigDto modify(I18nConfigDto i18nConfigDto) {
        // 根据业务修改
        updateById(i18nConfigDto);
        return i18nConfigDto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<I18nConfigDto> modifyBatch(List<I18nConfigDto> i18nConfigDtos) {
        // 根据业务修改
        return updateList(i18nConfigDtos);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<I18nConfigDto> saveOrModifyBatch(List<I18nConfigDto> i18nConfigDtos) {
        if (CollectionUtils.isEmpty(i18nConfigDtos)) {
            return new ArrayList<>();
        }

        List<I18nConfigDto> toInsert = new ArrayList<>();
        List<I18nConfigDto> toUpdate = new ArrayList<>();

        for (I18nConfigDto dto : i18nConfigDtos) {
            if (StringUtils.isBlank(dto.getNamespace()) || StringUtils.isBlank(dto.getKeyPath())) {
                continue;
            }

            QueryWrapper<I18nConfig> wrapper = new QueryWrapper<>();
            wrapper.eq("del_flag", BaseConstant.NO);
            wrapper.eq("locale", dto.getLocale());
            wrapper.eq("namespace", dto.getNamespace());
            wrapper.eq("key_path", dto.getKeyPath());

            List<I18nConfig> exists = i18nConfigMapper.selectList(wrapper);
            if (CollectionUtils.isEmpty(exists)) {
                dto.setDelFlag(BaseConstant.NO);
                if (StringUtils.isBlank(dto.getId())) {
                    dto.setId(UUIDGenerator.generateUUID());
                }
                toInsert.add(dto);
            } else {
                I18nConfig hit = exists.get(0);
                dto.setId(hit.getId());
                toUpdate.add(dto);
            }
        }

        if (!toInsert.isEmpty()) {
            insertList(toInsert);
        }
        if (!toUpdate.isEmpty()) {
            updateList(toUpdate);
        }

        return i18nConfigDtos;
    }

    @Override
    public void trueDeleteBatchWithLogic(List<I18nConfigDto> i18nConfigDtos) {
        if (CollectionUtils.isEmpty(i18nConfigDtos)) {
            return;
        }

        List<String> ids = new ArrayList<>();
        for (I18nConfigDto dto : i18nConfigDtos) {
            if (StringUtils.isBlank(dto.getNamespace()) || StringUtils.isBlank(dto.getKeyPath())) {
                continue;
            }

            QueryWrapper<I18nConfig> wrapper = new QueryWrapper<>();
            wrapper.eq("locale", dto.getLocale());
            wrapper.eq("namespace", dto.getNamespace());
            wrapper.eq("key_path", dto.getKeyPath());

            List<I18nConfig> exists = i18nConfigMapper.selectList(wrapper);
            if (CollectionUtils.isEmpty(exists)) {
                continue;
            }
            I18nConfig hit = exists.get(0);
            ids.add(hit.getId());

        }
        i18nConfigMapper.deleteByIds(ids);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) {
        // 根据业务修改
        I18nConfigDto i18nConfigDto = new I18nConfigDto();
        i18nConfigDto.setId(id);
        deleteById(i18nConfigDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteBatch(List<String> ids) {
        // 根据业务修改
        deleteByPrimaryKeys(ids);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public I18nConfigDto insert(I18nConfigDto i18nConfigDto) {
        i18nConfigDto.setId(UUIDGenerator.generateUUID());
        i18nConfigDto.setDelFlag(BaseConstant.NO);
        I18nConfig entity = BeanMapper.map(i18nConfigDto, I18nConfig.class);
        i18nConfigMapper.insert(entity);
        return i18nConfigDto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public I18nConfigDto insertWithId(I18nConfigDto i18nConfigDto) {
        if (StringUtils.isBlank(i18nConfigDto.getId())) {
            i18nConfigDto.setId(UUIDGenerator.generateUUID());
        }
        i18nConfigDto.setDelFlag(BaseConstant.NO);
        I18nConfig entity = BeanMapper.map(i18nConfigDto, I18nConfig.class);
        i18nConfigMapper.insert(entity);
        return i18nConfigDto;
    }

    private List<I18nConfigDto> insertList(List<I18nConfigDto> i18nConfigDtos) {
        if (CollectionUtils.isEmpty(i18nConfigDtos)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "批量插入时，参数不能为空");
        }
        List<I18nConfig> insertList = new ArrayList<>();
        for (I18nConfigDto i18nConfigDto : i18nConfigDtos) {
            if (StringUtils.isBlank(i18nConfigDto.getId())) {
                i18nConfigDto.setId(UUIDGenerator.generateUUID());
            }
            i18nConfigDto.setDelFlag(BaseConstant.NO);
            insertList.add(BeanMapper.map(i18nConfigDto, I18nConfig.class));
        }
        i18nConfigMapper.insert(insertList, 1000);
        return i18nConfigDtos;
    }

    private List<I18nConfigDto> updateList(List<I18nConfigDto> i18nConfigDtos) {
        if (CollectionUtils.isEmpty(i18nConfigDtos)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "批量更新时，参数不能为空");
        }
        for (I18nConfigDto i18nConfigDto : i18nConfigDtos) {
            if (StringUtils.isBlank(i18nConfigDto.getId())) {
                throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "批量更新时，主键不能为空");
            }
        }
        List<I18nConfig> i18nConfigList = BeanMapper.mapList(i18nConfigDtos, I18nConfigDto.class, I18nConfig.class);
        i18nConfigMapper.updateById(i18nConfigList, 1000);
        return i18nConfigDtos;
    }

    @Transactional(rollbackFor = Exception.class)
    public int updateById(I18nConfigDto i18nConfigDto) {
        if (StringUtils.isBlank(i18nConfigDto.getId())) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "更新时，主键不能为空");
        }
        I18nConfig entity = BeanMapper.map(i18nConfigDto, I18nConfig.class);
        return i18nConfigMapper.updateById(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    public int trueDeleteById(String id) {
        return i18nConfigMapper.deleteById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    public int deleteById(I18nConfigDto i18nConfigDto) {
        i18nConfigDto.setDelFlag(BaseConstant.YES);
        return updateById(i18nConfigDto);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteByPrimaryKeys(List<String> ids) {
        List<I18nConfigDto> i18nConfigDtos = new ArrayList<>();
        for (String id : ids) {
            I18nConfigDto i18nConfigDto = new I18nConfigDto();
            i18nConfigDto.setId(id);
            i18nConfigDto.setDelFlag(BaseConstant.YES);
            i18nConfigDtos.add(i18nConfigDto);
        }
        updateList(i18nConfigDtos);
    }

}
